package com.jl;

import com.baomidou.mybatisplus.annotation.TableName;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Update;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;

/**
 * 同步更新数值
 */
@Component
public class JLSyncUpdate {

    private static Util.Mapper mapper;

    @Autowired(required = false)
    private void setBaseMapper(JLSyncUpdate.Util.Mapper mapper) {
        JLSyncUpdate.mapper = mapper;
    }

    public Set update(Class<?> entity) {
        String tab = entity.getAnnotation(TableName.class).value();
        String sql = "update " + tab;
        return new Set(sql);
    }

    public static class Set {
        private String sql;

        public Set(String sql) {
            this.sql = sql;
        }

        public <T> SetWhere set(JLLambda.JLFunction<T, ?> jlFunction, BigDecimal value) {
            String property = JLLambda.getProperty(jlFunction);
            String propertys = JLStringTools.humpToLine(property);
            String updatecolu = String.format("%s + %s", propertys, value);
            sql += String.format(" set %s = %s", propertys, updatecolu);
            return new SetWhere(sql, updatecolu + " >= 0");
        }
    }

    public static class SetWhere {
        private String sql;

        private String updatecolu;

        public SetWhere(String sql, String updatecolu) {
            this.sql = sql;
            this.updatecolu = updatecolu;
        }

        public <T> SetWhere set(JLLambda.JLFunction<T, ?> jlFunction, BigDecimal value) {
            String property = JLLambda.getProperty(jlFunction);
            String propertys = JLStringTools.humpToLine(property);
            String updatecolu = String.format("%s + %s", propertys, value);
            sql += String.format(", %s = %s", propertys, updatecolu);
            this.updatecolu += " and " + updatecolu + " >= 0";
            return this;
        }

        public <T> Where eq(JLLambda.JLFunction<T, ?> jlFunction, Object propertyValue) {
            String property = JLLambda.getProperty(jlFunction);
            String propertys = JLStringTools.humpToLine(property);
            sql += String.format(" where %s = '%s'", propertys, propertyValue);
            return new Where(sql, updatecolu);
        }
    }

    public static class Where {
        private String sql;

        private String updatecolu;

        public Where(String sql, String updatecolu) {
            this.sql = sql;
            this.updatecolu = updatecolu;
        }

        public <T, R> Where eq(JLLambda.JLFunction<T, R> jlFunction, R value) {
            String property = JLLambda.getProperty(jlFunction);
            String propertys = JLStringTools.humpToLine(property);
            sql += String.format(" and %s = '%s'", propertys, value);
            return this;
        }

        public boolean exec() {
            sql += String.format(" and %s", updatecolu);
            int exec = mapper.exec(sql);
            return exec > 0 ? true : false;
        }

    }

    public static class Util {
        public interface Mapper {
            @Update("${sql}")
            int exec(@Param("sql") String sql);
        }
    }

}
